#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include <sstream>
#include "bmock_util.hpp"
#include "detail/bmock_in_out_raw_mem_ptr.hpp"
#include "bmock_in_out_raw_mem.hpp"
#include "detail/bmock_test_control_tools.hpp"

namespace bmock {
	static const control_tools_ptr                   tl(new test_control_tools());
	static const char                                name[]   = "arg";
	static const unsigned char                       val1[]   = {0x00,0x01,0x02,0xF1,0xF2};
	static const std::string                              s_val1   = "000102F1F2";
	static const size_t                              LEN1     = sizeof(val1);
	static const unsigned char                       val2[]   = {0xA0,0xA1,0xA2,0xB1,0xB2};
	static const size_t                              LEN2     = sizeof(val2);
	static const std::string                              s_val2   = "A0A1A2B1B2";

	BOOST_AUTO_TEST_CASE(test_in_out_raw_mem_ptr_get_value) {
		const in_out_raw_mem_descr<unsigned char> rm(val1,LEN1,val2,LEN2);
		const arg_val_ptr p_val(new in_out_raw_mem_ptr(name,raw_mem(rm.get_ptr(),LEN1)));
		arg_checker       al(tl);
		const arg_val_str expected(s_val1,s_val2);

		BOOST_CHECK_EQUAL(expected,p_val->get_value(al));
	}

	BOOST_AUTO_TEST_CASE(test_in_out_raw_mem_ptr_print) {
		const raw_mem     rm1(val1,LEN1);
		const arg_val_ptr p_val(new in_out_raw_mem_ptr(name,rm1));
		const std::string      expected = std::string("IN_OUT(")+rm1.get_value()+","+out_arg_val::UNKNOWN+")";
		std::ostringstream        os;

		BOOST_CHECK_NO_THROW(p_val->print(os));
		BOOST_CHECK_EQUAL(expected,os.str());
	}

	BOOST_AUTO_TEST_CASE(test_in_out_raw_mem_arg_val_validate) {
		const arg_val_ptr p_val(new in_out_raw_mem_ptr(name,raw_mem(val1,LEN1)));
		arg_checker       al(tl);
		const arg_val_str expected(s_val1,s_val2);
		bool              status = true;

		al.set_location(location(__FILE__,__LINE__+1));
		BOOST_CHECK_NO_THROW(status = p_val->validate(al,expected));
		BOOST_CHECK(!status);
	}

	BOOST_AUTO_TEST_CASE(test_in_out_raw_mem_arg_val_update) {
		unsigned char y_val[LEN2];
		std::fill_n(y_val,LEN2,0);
		const arg_val_ptr   p_val(new in_out_raw_mem_ptr(name,raw_mem(y_val,LEN2)));
		const arg_val_str   expected("",s_val2);
		arg_checker         ac(tl);

		ac.set_location(location(__FILE__,__LINE__+1));
		BOOST_CHECK_NO_THROW(p_val->update(ac,expected));
		BOOST_CHECK_EQUAL(LEN2,mismatch_at(y_val,y_val+LEN2,val2));
	}

	BOOST_AUTO_TEST_CASE(test_in_out_in_raw_mem_ptr_get_value) {
		const in_out_raw_mem_descr<unsigned char> rm1 = in_raw_mem(val1,LEN1);
		const arg_val_ptr p_val(new in_out_raw_mem_ptr(name,raw_mem(rm1.get_ptr(),LEN1)));
		arg_checker       al(tl);
		const arg_val_str expected(s_val1,IGNORE_STR);

		BOOST_CHECK_EQUAL(expected,p_val->get_value(al));
	}

	BOOST_AUTO_TEST_CASE(test_in_out_out_raw_mem_ptr_get_value) {
		const in_out_raw_mem_descr<unsigned char> rm2 = out_raw_mem(val2,LEN2);
		const arg_val_ptr p_val(new in_out_raw_mem_ptr(name,raw_mem(rm2.get_ptr(),LEN2)));
		arg_checker       al(tl);
		const arg_val_str expected(IGNORE_STR,s_val2);

		BOOST_CHECK_EQUAL(expected,p_val->get_value(al));
	}
}
